package com.party.admin.web.controller.wallet;

import com.party.admin.biz.file.ExcelExportService;
import com.party.admin.biz.order.OrderBizService;
import com.party.admin.utils.excel.ExportExcel;
import com.party.admin.web.dto.AjaxResult;
import com.party.admin.web.dto.input.common.CommonInput;
import com.party.admin.web.dto.output.wallet.WithdrawalOutput;
import com.party.common.paging.Page;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.LangUtils;
import com.party.common.utils.StringUtils;
import com.party.common.utils.VerifyCodeUtils;
import com.party.core.model.BaseModel;
import com.party.core.model.member.Member;
import com.party.core.model.wallet.WithdrawalStatus;
import com.party.core.model.wallet.Withdrawals;
import com.party.core.service.member.IMemberService;
import com.party.core.service.wallet.IWithdrawalService;
import com.party.core.service.wallet.biz.WithdrawalsBizService;
import com.party.notify.notifyPush.officialPartner.ICopartnerNotifySendService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 提现申请
 *
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/wallet/withdrawals")
public class WithdrawalsController {

	@Autowired
	private IMemberService memberService;

	@Autowired
	private OrderBizService orderBizService;

	@Autowired
	private IWithdrawalService withdrawalService;

	@Autowired
	private WithdrawalsBizService withdrawalsBizService;

	@Autowired
	private ExcelExportService excelExportService;

    @Autowired
    private ICopartnerNotifySendService copartnerNotifySendService;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 提现记录
     *
     * @param page
     * @return
     */
    @RequestMapping("withdrawalList")
    public ModelAndView withdrawalList(Withdrawals withdrawal, Page page, CommonInput commonInput) {
        ModelAndView mv = new ModelAndView("wallet/withdrawalList");
        page.setLimit(15);
        withdrawal.setDelFlag(BaseModel.DEL_FLAG_NORMAL);

		Map<String, Object> params = CommonInput.appendParams(commonInput);
		if(withdrawal.getType()==null||0==withdrawal.getType()){

			List<Integer> types = new ArrayList<>();
			types.add(Withdrawals.TYPE_BROKERAGE);
			types.add(Withdrawals.TYPE_MALL);
			types.add(Withdrawals.TYPE_CROWD_FUNDING);
			types.add(Withdrawals.TYPE_ACTIVITY);
			params.put("types",types);

			withdrawal.setType(null);
		}

		if(Withdrawals.TYPE_CROWD_FUNDING!=withdrawal.getType()){
			withdrawal.setEventName(null);
		}

		mv.addObject("input", commonInput);

		Map<Integer, String> checkStatus = WithdrawalStatus.convertMap();
		mv.addObject("checkStatus", checkStatus);

		List<Withdrawals> withdrawals = withdrawalService.webListPage(withdrawal, params, page);
		List<WithdrawalOutput> channelOutputs = LangUtils.transform(withdrawals, input -> {
			WithdrawalOutput output = WithdrawalOutput.transform(input);

			String account = input.getAccountNumber();
			account = withdrawalsBizService.formatAccountNumber(account);
			output.setAccountNumber(account);


			Double withdrawalCharge = input.getWithdrawalCharge();
			withdrawalCharge = withdrawalCharge==null? 0d:withdrawalCharge;

			//提现金额X（平台提现手续费+微信提现手续费）
			double serviceFee = BigDecimalUtils.mul(input.getPayment(), Withdrawals.SERVER_FEE+withdrawalCharge);
			serviceFee = BigDecimalUtils.round(serviceFee, 2);


			// 净额
			double netAmount = BigDecimalUtils.sub(input.getPayment(), serviceFee);

			output.setServiceFee(serviceFee);
			output.setNetAmount(netAmount);
			return output;
		});
		mv.addObject("withdrawals", channelOutputs);
		mv.addObject("withdrawal", withdrawal);
		mv.addObject("page", page);
		return mv;
	}

	/**
	 * 审核
	 *
	 * @param withdrawal
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "verify")
	public AjaxResult verify(Withdrawals withdrawal, HttpServletRequest request) {
		if (StringUtils.isNotEmpty(withdrawal.getId())) {
			Integer status = withdrawal.getStatus();
			Withdrawals entity = withdrawalService.get(withdrawal.getId());
			if (entity == null) {
				return AjaxResult.error("审核失败，状态错误");
			}

			if (status.equals(WithdrawalStatus.STATUS_AUDIT_PASS.getCode())) {
				// 通过
				entity.setRemarks(withdrawal.getRemarks());
				entity.setStatus(status);
				withdrawalService.update(entity);
				return new AjaxResult(true, "审核成功");
			} else if (status.equals(WithdrawalStatus.STATUS_AUDIT_REJECT.getCode())) {
				// 拒绝
				entity.setRemarks(withdrawal.getRemarks());
				entity.setStatus(status);
				entity.setUpdateDate(new Date());
				withdrawalService.update(entity);

				if (entity.getType().equals(Withdrawals.TYPE_BROKERAGE)) {
					try {
						Member receiver = memberService.get(entity.getCreateBy());
						copartnerNotifySendService.sendBrokerageWithdrawalFail(entity, receiver);
					} catch (Exception e) {
						logger.error("佣金提现审核拒绝推送异常", e);
					}
				}

				return new AjaxResult(true, "审核成功");
			} else if (status.equals(WithdrawalStatus.STATUS_HAVE_PAID.getCode())) {
				entity.setRemarks(withdrawal.getRemarks());
				entity.setStatus(status);
				entity.setPayDate(new Date());
				withdrawalService.update(entity);

				if (entity.getType().equals(Withdrawals.TYPE_BROKERAGE)) {
					try {
						Member receiver = memberService.get(entity.getCreateBy());
						copartnerNotifySendService.sendBrokerageWithdrawalPass(entity, receiver);
					} catch (Exception e) {
						logger.error("佣金提现审核通过推送异常", e);
					}
				}
				return new AjaxResult(true, "标记为付款成功");
			}
		}
		return null;
	}

	/**
	 * 提现记录导出
	 *
	 * @param withdrawal
	 * @param commonInput
	 * @param response
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "exportWithdrawal", method = RequestMethod.POST)
	public AjaxResult exportWithdrawal(Withdrawals withdrawal, CommonInput commonInput, HttpServletResponse response) {
		try {
            Map<String, Object> params = CommonInput.appendParams(commonInput);
			String fileName = "提现明细.xlsx";
			withdrawal.setDelFlag(BaseModel.DEL_FLAG_NORMAL);

			if (withdrawal.getType() == null || 0 == withdrawal.getType()) {
				List<Integer> types = new ArrayList<>();
				types.add(Withdrawals.TYPE_BROKERAGE);
				types.add(Withdrawals.TYPE_MALL);
				types.add(Withdrawals.TYPE_CROWD_FUNDING);
				types.add(Withdrawals.TYPE_ACTIVITY);
				params.put("types", types);
				withdrawal.setType(null);
			}

			if (Withdrawals.TYPE_CROWD_FUNDING != withdrawal.getType()) {
				withdrawal.setEventName(null);
			}
			List<Withdrawals> withdrawals = withdrawalService.webListPage(withdrawal, params, null);
			List<WithdrawalOutput> withdrawalOutputs = LangUtils.transform(withdrawals, input -> {
				WithdrawalOutput output = WithdrawalOutput.transform(input);
				String account = input.getAccountNumber();
				account = withdrawalsBizService.formatAccountNumber(account);
				output.setAccountNumber(account);

				// 手续费
				double serviceFee = BigDecimalUtils.mul(input.getPayment(), Withdrawals.SERVER_FEE);
				serviceFee = BigDecimalUtils.round(serviceFee, 2);
				// 净额
				double netAmount = BigDecimalUtils.sub(input.getPayment(), serviceFee);

				output.setServiceFee(serviceFee);
				output.setNetAmount(netAmount);

				String value = WithdrawalStatus.getValue(input.getStatus());
				output.setStatus2(value);

				if (input.getType().equals(Withdrawals.TYPE_BALANCE)) {
					output.setTypeName("余额");
				} else if (input.getType().equals(Withdrawals.TYPE_BROKERAGE)) {
					output.setTypeName("佣金");
				}
				return output;
			});
			ExportExcel exportExcel = new ExportExcel("", WithdrawalOutput.class).setDataList(withdrawalOutputs);
			String allPath = excelExportService.getExcelPath(fileName, "wallet", exportExcel);
			return AjaxResult.success((Object) allPath);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return AjaxResult.error("导出异常");
	}

    /**
     * 个人中心 提现明细
     *
     * @param page
     * @return
     */
    @RequestMapping("memberWithdrawList")
    public ModelAndView memberWithdrawList(String mmId, Page page) {
        ModelAndView mv = new ModelAndView("system/member/withdrawList");
        page.setLimit(20);
        Withdrawals withdrawal = new Withdrawals();
        withdrawal.setCreateBy(mmId);
        withdrawal.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        List<Withdrawals> withdrawals = withdrawalService.listPage(withdrawal, page);
        List<WithdrawalOutput> withdrawalOutputs = LangUtils.transform(withdrawals, input -> {
            WithdrawalOutput output = WithdrawalOutput.transform(input);
            String account = input.getAccountNumber();
            account = withdrawalsBizService.formatAccountNumber(account);
            output.setAccountNumber(account);

            // 手续费
            double serviceFee = BigDecimalUtils.mul(input.getPayment(), Withdrawals.SERVER_FEE);
            serviceFee = BigDecimalUtils.round(serviceFee, 2);
            // 净额
            double netAmount = BigDecimalUtils.sub(input.getPayment(), serviceFee);

            output.setServiceFee(serviceFee);
            output.setNetAmount(netAmount);
            return output;
        });
        mv.addObject("withdrawals", withdrawalOutputs);
        mv.addObject("page", page);

        // 提现总额
        Double withdrawalTotal = withdrawalsBizService.getWithdrawalTotal(mmId, Withdrawals.TYPE_BALANCE,null);
		mv.addObject("withdrawalTotal", withdrawalTotal);

		Map<String, Object> resultParams = orderBizService.memberInfoBiz(mmId);
        mv.addAllObjects(resultParams);
		return mv;
    }

    @ResponseBody
	@RequestMapping("initData")
    public AjaxResult initData() {
    	List<Withdrawals> withdrawals = withdrawalService.list(new Withdrawals());
    	for (Withdrawals withdrawal : withdrawals) {
			String orderNum = VerifyCodeUtils.generateOrderNum(withdrawal.getCreateDate());
    		withdrawal.setOrderNum(orderNum);
			withdrawalService.update(withdrawal);
		}
		return AjaxResult.success();
	}
}
